﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Collections.Specialized;
namespace EQual.Infrastructure.MVPFramework.Models
{
    /// <summary>
    /// this aiming the list views and passed as a DataContext to a Wpf ItemsControl 
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public abstract class PresentationModelBase<T> : EQual.Infrastructure.MVPFramework.Models.IPresentationModelBase<T>  where T : DataAccesLayer .DomainModel .BaseDataAccesObject 
    {
        protected DataAccesLayer.EQualDataLayerFactory DataFactory;
        public event PropertyChangedEventHandler PropertyChanged;
        public event NotifyCollectionChangedEventHandler ModelCollectionChanged;

        public IEnumerable<T> ItemsCollection
        {
            get { return WrappedCollection(); }
        }

        /// <summary>
        /// Wrappe up the collection so we can observe all the changes in collection
        /// </summary>
        /// <returns></returns>
        protected  IEnumerable<T> WrappedCollection()
        {
            WpfApplicationExperimental.DAOCollection<T> items;
            System.Collections.Generic.IEnumerable<T> collection = GetCollection();

            if (collection == null)
                items = new WpfApplicationExperimental.DAOCollection<T>();
            else
                items = new WpfApplicationExperimental.DAOCollection<T>(collection);

            items.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(CollectionChanged);

            return FilteredItems(items);
        }

        /// <summary>
        /// if more selection on the collection is needed .this is decorator and pipes and filters patterns
        /// </summary>
        /// <param name="items"></param>
        /// <returns></returns>
        protected virtual IEnumerable <T> FilteredItems(WpfApplicationExperimental.DAOCollection<T> items)
        {
            return items;
        }

        protected virtual void CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            if(this .ModelCollectionChanged != null )
            this.ModelCollectionChanged(this, e);
        }

        /// <summary>
        /// Gets the collection that will be passed to view .
        /// </summary>
        /// <returns></returns>
        protected abstract IEnumerable<T> GetCollection();

        protected  void InvokePropertyChanged(PropertyChangedEventArgs e)
        {
            PropertyChangedEventHandler Handler = PropertyChanged;
            if (Handler != null)
            {
                Handler(this, e);
            }
        }

    }

    public class DefaulPresentationModel<Ttype> : PresentationModelBase<Ttype> where Ttype : DataAccesLayer .DomainModel .BaseDataAccesObject 
    {
        public DefaulPresentationModel() : base() { }

        public CollectionProvider ItemsCollectionProvider;
        protected override IEnumerable<Ttype> GetCollection()
        {
            if (ItemsCollectionProvider != null)
                return ItemsCollectionProvider();
            else return null;
        }


        public   delegate IEnumerable<Ttype> CollectionProvider();
    }
}
